#include "Snake.h"
#include <graphics.h>
#include <tchar.h>
#include <Windows.h>
#include <iostream>

#define block_width 20
#define x_origin 0
#define y_origin 0

Snake::Snake() {
    int snake[2][2] = {
        {14, 11},
        {13, 11}
    };
    body.resize(2, std::vector<int>(2, 0));
    for (int i = 0; i < body.size(); i++) {
        for (int j = 0; j < body[i].size(); j++) {
            body[i][j] = snake[i][j];
        }
    }
}

void Snake::drawUnitBlock(int body_x, int body_y, const char* pic) {
    int left = body_x * block_width + x_origin;
    int top = body_y * block_width + y_origin;
    IMAGE img;
    int len = MultiByteToWideChar(CP_ACP, 0, pic, -1, NULL, 0);
    wchar_t* wPic = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, pic, -1, wPic, len);
    loadimage(&img, wPic, block_width, block_width);
    delete[] wPic;
    putimage(left, top, &img);
}

void Snake::eraseUnitBlock(int body_x, int body_y) {
    int left = body_x * block_width + x_origin;
    int right = block_width + left;
    int top = body_y * block_width + y_origin;
    int bottom = block_width + top;
    setcolor(RGB(239, 255, 150));
    setfillcolor(RGB(239, 255, 150));
    fillrectangle(left, top, right, bottom);
}

void Snake::draw() {
    for (int i = 0; i < body.size(); i++) {
        if (i == 0) {
            drawUnitBlock(body[i][0], body[i][1], "head.png");
        }
        else {
            drawUnitBlock(body[i][0], body[i][1], "body.png");
        }
    }
}

void Snake::move(char inPut) {
    std::vector<int> inrow(2, 0);
    switch (inPut) {
    case 'a': // 左
        if (body[0][0] == body[1][0] + 1) { return; }
        inrow[0] = body[0][0] - 1;
        inrow[1] = body[0][1];
        break;
    case 's': // 下
        if (body[0][1] == body[1][1] - 1) { return; }
        inrow[0] = body[0][0];
        inrow[1] = body[0][1] + 1;
        break;
    case 'd': // 右
        if (body[0][0] == body[1][0] - 1) { return; }
        inrow[0] = body[0][0] + 1;
        inrow[1] = body[0][1];
        break;
    case 'w': // 上
        if (body[0][1] == body[1][1] + 1) { return; }
        inrow[0] = body[0][0];
        inrow[1] = body[0][1] - 1;
        break;
    default: // 忽略其他按键
        return; // 直接返回，不执行后续操作
    }
    // 检查移动后的坐标是否合法
    if (inrow[0] < 4 || inrow[0] > 23 || inrow[1] < 4 || inrow[1] > 19) {
        return; // 移动超出边界则不执行
    }
    body.insert(body.begin(), inrow);
    switch (inPut) {
    case 'a': // 左
        drawUnitBlock(body[0][0], body[0][1], "head_left.png");
        break;
    case 's': // 下
        drawUnitBlock(body[0][0], body[0][1], "head_down.png");
        break;
    case 'd': // 右
        drawUnitBlock(body[0][0], body[0][1], "head_right.png");
        break;
    case 'w': // 上
        drawUnitBlock(body[0][0], body[0][1], "head_up.png");
        break;
    default: // 忽略其他按键
        return; // 直接返回，不执行后续操作
    }
    drawUnitBlock(body[1][0], body[1][1], "body.png");
}
void Snake::autoMove() {
    std::vector<int> inrow(2, 0);
    if (body[0][0] == body[1][0] + 1) {
        inrow[0] = body[0][0] + 1;
        inrow[1] = body[0][1];
    }
    else if (body[0][0] == body[1][0] - 1) {
        inrow[0] = body[0][0] - 1;
        inrow[1] = body[0][1];
    }
    else if (body[0][1] == body[1][1] + 1) {
        inrow[0] = body[0][0];
        inrow[1] = body[0][1] + 1;
    }
    else if (body[0][1] == body[1][1] - 1) {
        inrow[0] = body[0][0];
        inrow[1] = body[0][1] - 1;
    }
    body.insert(body.begin(), inrow);
    if (inrow[0] == body[1][0] + 1) {
        drawUnitBlock(body[0][0], body[0][1], "head_right.png");
    }
    else if (inrow[0] == body[1][0] - 1) {
        drawUnitBlock(body[0][0], body[0][1], "head_left.png");
    }
    else if (inrow[1] == body[1][1] + 1) {
        drawUnitBlock(body[0][0], body[0][1], "head_down.png");
    }
    else if (inrow[1] == body[1][1] - 1) {
        drawUnitBlock(body[0][0], body[0][1], "head_up.png");
    }
    drawUnitBlock(body[1][0], body[1][1], "body.png");
}

void Snake::removeTail() {
    eraseUnitBlock(body[body.size() - 1][0], body[body.size() - 1][1]);
    body.erase(body.end() - 1, body.end());
}

std::vector<int> Snake::getHead() {
    return body[0];
}

std::vector<std::vector<int>> Snake::getBody() {
    return body;
}